package client;

import java.util.List;

import client.admin.AdminManager;
import client.dtos.RepositoryFileDTO;
import client.dtos.RevisionDTO;
import client.ui.RepositoryEditingDialogBox;
import client.ui.RepositoryFileHistoryDialog;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class Main implements EntryPoint {
	
	private final DecoratedTabPanel tabPanel = new DecoratedTabPanel();
	
	public void onModuleLoad() {
		tabPanel.setAnimationEnabled(true);
		tabPanel.add(buildOverviewPanelContents(), "Overview");
		tabPanel.add(buildSearchPanelContents(), "Normal Search");
		//tp.add(new HTML("FirstLast Search"), "First/Last");
		//tp.add(new HTML("Repository Search"), "Repository Search");
		tabPanel.add(buildAdminPanelContents(), "Admin");
		tabPanel.selectTab(0);
		tabPanel.setWidth("100%");
		RootPanel.get().add(tabPanel);
		
		
	}

	private Widget buildOverviewPanelContents() {
		return new HTML("Overview");
	}

	private VerticalPanel buildAdminPanelContents() {
		final VerticalPanel vp = new VerticalPanel();
		final FlexTable ft = new FlexTable();
		final AdminManager adminManager = new AdminManager(ft);
		//adminManager.refresh();
		vp.add(ft);
		
		final HorizontalPanel hp = new HorizontalPanel();
		final Button addRepositoryButton = new Button("Add"); 
		addRepositoryButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				final RepositoryEditingDialogBox red = new RepositoryEditingDialogBox();
				red.addOkClickHandler(new ClickHandler() {

					public void onClick(ClickEvent event) {
						adminManager.saveNewRepository(red.getRepository());
						red.hide();
					}
					
				});
				red.show();
			}
			
		});
		hp.add(addRepositoryButton);
		vp.add(hp);
		
		return vp;
	}

	private Widget buildSearchPanelContents() {
		final VerticalPanel tablePanel = new VerticalPanel();
		final DockPanel dp = new DockPanel();
		
		final TextBox searchBox = new TextBox();
		final CheckBox searchAnywhereCheckBox = new CheckBox("Search whole path");
		searchAnywhereCheckBox.setVisible(false);
		final ListBox lb = new ListBox();
		lb.addItem("Commit comments");
		lb.addItem("Path");
		lb.addChangeHandler(new ChangeHandler() {

			public void onChange(ChangeEvent event) {
				if ("Path".equals(lb.getItemText(lb.getSelectedIndex()))) {
					searchAnywhereCheckBox.setVisible(true);
				} else {
					searchAnywhereCheckBox.setVisible(false);
				}
			}
			
		});
		
		final HorizontalPanel searchPanel = new HorizontalPanel();
		searchPanel.add(searchBox);
		searchPanel.add(lb);
		searchPanel.add(searchAnywhereCheckBox);
		
		final HorizontalPanel buttonPanel = new HorizontalPanel();
		buttonPanel.setSpacing(2);
		final Button searchButton = new Button("Search");
		searchButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				if (tablePanel.getWidgetCount()>0) {
					final FlexTable oldTable = (FlexTable)tablePanel.getWidget(0);
					oldTable.clear();
					tablePanel.remove(0);
				}
				final FlexTable ft = new FlexTable();
				ft.setBorderWidth(1);
				ft.setVisible(false);
				tablePanel.add(ft);
				final String searchTerm = searchBox.getText();
				final String searchScope = lb.getItemText(lb.getSelectedIndex());
				final SearchServiceAsync searchService = (SearchServiceAsync)GWT.create(SearchService.class);
				
				if ("Path".equalsIgnoreCase(searchScope)) {
					searchService.search(searchTerm, searchAnywhereCheckBox.getValue(), new AsyncCallback<List<RepositoryFileDTO>>() {
	
						public void onSuccess(List<RepositoryFileDTO> result) {
							int row = 0;
							for (final RepositoryFileDTO rfDTO : result) {
								ft.setText(row, 0, rfDTO.getPath());
								final Button historyButton = new Button("History");
								historyButton.addClickHandler(new ClickHandler() {
	
									public void onClick(ClickEvent event) {
										final RepositoryFileHistoryDialog dialog = new RepositoryFileHistoryDialog(rfDTO);
										dialog.show();
									}
									
								});
								ft.setWidget(row, 1, historyButton);
								final Button hideButton = new Button("Hide");
								final int rowReference = row;
								hideButton.addClickHandler(new ClickHandler() {

									public void onClick(ClickEvent event) {
										searchService.hideRepositoryFile(rfDTO.getRepositoryFileID(), new AsyncCallback<Void>() {

											public void onFailure(Throwable caught) {
												Window.alert("Error while hiding file:" + caught.getMessage());
											}

											public void onSuccess(Void result) {
												ft.removeRow(rowReference);
											}
											
										});
									}
									
								});
								ft.setWidget(row, 2, hideButton);
								++row;
							}
							ft.setVisible(true);
						}
						
						public void onFailure(Throwable caught) {
							Window.alert("Error:"+caught.getMessage());
						}
					});
				} else if ("Commit comments".equalsIgnoreCase(searchScope)) {
					searchService.searchComments(searchTerm, new AsyncCallback<List<RevisionDTO>>() {

						public void onFailure(Throwable caught) {
							Window.alert("Error "+caught.getMessage());
						}

						public void onSuccess(List<RevisionDTO> result) {
							int row = 0;
							//final DateFormat df = DateFormat.getDateTimeInstance();
							for (final RevisionDTO rfDTO : result) {
								ft.setText(row, 0, ""+rfDTO.getRevision());
								//ft.setText(row, 1, df.format(rfDTO.getRevisionDate()));
								ft.setText(row, 1, rfDTO.getRevisionUser());
								ft.setText(row, 2, rfDTO.getRevisionMessage());
								++row;
							}
							ft.setVisible(true);
						}

						
					});
				}
			}
		});
		buttonPanel.add(searchButton);
		
		dp.add(searchPanel, DockPanel.NORTH);
		dp.add(buttonPanel, DockPanel.NORTH);
		dp.add(tablePanel, DockPanel.CENTER);
		dp.add(new Label("Hiding a result means it will no longer appear in search results"), DockPanel.SOUTH);
		return dp;
	}

}
